package basicConcepts;

public class SimpleGenericsExample<I> {

	private abstract class AGenericAbstractClass<T> {
		public abstract T anAbstractMethod(T t, I i);
	}

	private interface AGenericInterface<I> {
		public I anInterfaceMethod(I i);
	}

	private class AGenericClass<E, T> extends AGenericAbstractClass<T>
			implements AGenericInterface<I> {
		@Override
		public I anInterfaceMethod(I i) {
			System.out
					.println("GenericsExample.AGenericClass.anInterfaceMethod()"+i.getClass());
			return i;
		}

		@Override
		public T anAbstractMethod(T t, I i) {
			System.out
					.println("GenericsExample.AGenericClass.anAbstractMethod()"+t.getClass()+"  "+i.getClass());
			return t;
		}
		
		public E aNonAbstractMethod(E e){
			System.out
					.println("GenericsExample.AGenericClass.aNonAbstractMethod()"+e.getClass());
			return e;
		}

	}

	public static void main(String[] args) {
		SimpleGenericsExample<String> aGenericsExample = new SimpleGenericsExample<String>();

		SimpleGenericsExample<String>.AGenericClass<Float, StringBuilder> aGenericClass = aGenericsExample.new AGenericClass<Float, StringBuilder>();
		
		SimpleGenericsExample<String>.AGenericClass<Float, StringBuilder> anotherGenericClassObject = aGenericsExample.new AGenericClass<>();
		
		aGenericClass.anInterfaceMethod("yellow");
		aGenericClass.anAbstractMethod(new StringBuilder("one more string"), "stringBuilder ");
		aGenericClass.aNonAbstractMethod((float) 2.4);
		System.out.println("=============================");
		anotherGenericClassObject.anInterfaceMethod("yellow");
		anotherGenericClassObject.anAbstractMethod(new StringBuilder("one more string"), "stringBuilder ");
		anotherGenericClassObject.aNonAbstractMethod((float) 2.4);

	}

}
